package com.itheima.controller.user;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.entity.Result;
import com.itheima.pojo.User;
import com.itheima.service.user.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * @author 郭文亮
 * @since 2021/11/4 11:50
 */

/**
 * @author 胡桂明
 * @since 2021/11/5 19:45
 */
@RestController
@RequestMapping("user")
public class UserController {
    /**
     * 默认记住密码，状态码为yes
     */
    private static final String DEFAULT_REMEMBER = "yes";
    /**
     * 默认自动登录，状态码为yes
     */
    private static final String DEFAULT_AUTOLOGIN = "yes";

    @Reference
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 登录功能
     *
     * @param username  登录账号
     * @param password  登录密码
     * @param remember  是否记住密码
     * @param autoLogin 是否自动登录
     * @return flag，message
     */
    @GetMapping("login.do")
    public Result login(String username, String password, String remember, String autoLogin, HttpServletRequest request, HttpServletResponse response) {
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        Boolean flag = userService.findUserByUsernameAndPassword(user);
        // 存储登录账户到session中
        setUsername(username, request, flag);
        // 记住密码处理
        remember(flag, username, password, remember, response);
        // 自动登录处理
        autoLogin(autoLogin, response, user, flag);
        return new Result(flag, flag ? MessageConstant.QUERY_LOGIN_SUCCESS : MessageConstant.QUERY_LOGIN_FAIL);
    }

    /**
     * 退出登录
     *
     * @param request  请求体，主要获取cookie
     * @param response 进行重定向
     * @throws IOException 请求异常
     */
    @GetMapping("logout.do")
    public Result logout(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            // 退出时将存储在cookie中的token清空
            if ("token".equals(cookie.getName())) {
                cookie.setValue(null);
                response.addCookie(cookie);
            }
        }
        // 退出时，将session中的username清空
        request.getSession().setAttribute("username", null);
        // 重定向返回登录界面
        return new Result(true, "退出成功");
    }

    /**
     * 从session中获取当前登录用户名
     * @param request 请求体，主要获取请求中存在cookie中的sessionId
     * @return 返回获取的结果
     * @throws IOException 请求异常
     */
    @GetMapping("getUsername.do")
    public Result getUsername(HttpServletRequest request) throws IOException {
        String username = (String) request.getSession().getAttribute("username");
        boolean flag = true;
        if (username == null || "".equals(username)) {
            flag = false;
        }
        return new Result(flag, flag ? "获取登录名成功" : "获取登录名失败", username);
    }

    /**
     * 用户注册
     * @param request 请求体，用户获取注册的参数
     * @return flag，message
     */
    @RequestMapping("/register.do")
    public Result register(HttpServletRequest request) {
        // 获取参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String code = request.getParameter("code");

        // 验证码正确
        if (code.equals(request.getSession().getAttribute("code"))) {
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            // 调用服务层
            Boolean flag = userService.register(user);
            // 响应数据
            return new Result(flag, "注册成功,即将返回登录界面。。。");
        } else {
            return new Result(false, "验证码错误");
        }

    }

    /**
     * 获取短信验证码
     * @param request 请求体，发送的邮箱
     */
    @RequestMapping("/register/getCode.do")
    public void registerGetCode(HttpServletRequest request) {
        String email = request.getParameter("email");
        String code = userService.getCode(email);
        // 数据处理
        request.getSession().setAttribute("code", code);
    }

    /**
     * 自动登录，通过token读取redis中数据user
     *
     * @param request 请求体
     * @throws IOException      读取redis异常
     * @throws ServletException 异常
     */
    @GetMapping("autoLogin.do")
    public Result autoLogin(HttpServletRequest request) throws IOException, ServletException {
        Cookie[] cookies = request.getCookies();
        String token = null;
        Boolean flag = false;
        for (Cookie cookie : cookies) {
            if ("token".equals(cookie.getName())) {
                token = cookie.getValue();
            }
        }
        if (Objects.isNull(token) || token == "") {
        } else {
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonUser = (String) redisTemplate.opsForValue().get("user:token:" + token);
            User user = objectMapper.readValue(jsonUser, User.class);
            request.getSession().setAttribute("username", user.getUsername());
            flag = userService.findUserByUsernameAndPassword(user);
        }
        return new Result(flag, flag ? MessageConstant.QUERY_LOGIN_SUCCESS : MessageConstant.QUERY_LOGIN_FAIL);
    }

    /**
     * 获取cookie中记住的账号和密码
     *
     * @param request 请求体
     * @return username, password
     */
    @GetMapping("getCookie.do")
    public User getCookie(HttpServletRequest request) {
        String username = null;
        String password = null;
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if ("username".equals(cookie.getName())) {
                username = cookie.getValue();
            } else if ("password".equals(cookie.getName())) {
                password = cookie.getValue();
            }
        }
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        return user;
    }

    /**
     * 登录成功后，将username存储到session中
     *
     * @param username 登录账户
     * @param request  请求体，用户存储session
     * @param flag     登录状态，是否登录成功
     */
    private void setUsername(String username, HttpServletRequest request, Boolean flag) {
        if (flag) {
            // 登录成功后，将username存入session中
            request.getSession().setAttribute("username", username);
        }
    }

    /**
     * 自动登录，生成token到redis，redis中以token为key，user为value
     *
     * @param autoLogin 是否自动登录
     * @param response  响应体，返回cookie
     * @param user      存入user账号和密码
     * @param flag      登录验证结果
     */
    private void autoLogin(String autoLogin, HttpServletResponse response, User user, Boolean flag) {
        if (flag && DEFAULT_AUTOLOGIN.equals(autoLogin)) {
            String token = userService.getTokenToRedis(user);
            Cookie cookieToken = new Cookie("token", token);
            cookieToken.setMaxAge(60 * 60 * 24 * 7);
            response.addCookie(cookieToken);
        }
    }

    /**
     * 登录记住密码，通过cookie实现，数据存储两周
     *
     * @param flag     是否登录成功
     * @param username 登录账户
     * @param password 登录密码
     * @param remember 是否记住密码
     * @param response 响应体
     */
    private void remember(Boolean flag, String username, String password, String remember, HttpServletResponse response) {
        // 记住密码,将用户名和密码存入cookie两周
        Cookie cookieUsername;
        Cookie cookiePassword;
        if (flag && DEFAULT_REMEMBER.equals(remember)) {
            cookieUsername = new Cookie("username", username);
            cookiePassword = new Cookie("password", password);
            cookieUsername.setMaxAge(60 * 60 * 24 * 14);
            cookiePassword.setMaxAge(60 * 60 * 24 * 14);
        } else {
            cookieUsername = new Cookie("username", null);
            cookiePassword = new Cookie("password", null);
            cookieUsername.setMaxAge(0);
            cookiePassword.setMaxAge(0);
        }
        response.addCookie(cookieUsername);
        response.addCookie(cookiePassword);
    }

    /**
     * 新增
     *
     * @param user 前端json获取数据
     */
    @PostMapping("add")
    public void save(@RequestBody User user) {
        userService.save(user);
    }

    /**
     * 删除
     *
     * @param id 前端获取要删除的id
     * @return 返回结果
     */
    @DeleteMapping("delete/{id}")
    public Result delete(@PathVariable int id) {
        userService.delete(id);
        return new Result(true, "删除成功！");
    }

    /**
     * 修改
     *
     * @param user 前端json获取数据
     */
    @PostMapping("update")
    public void update(@RequestBody User user) {
        userService.update(user);
    }

    /**
     * 按ID查找-修改用
     *
     * @param id 查询条件
     * @return 返回结果
     */
    @GetMapping("findById/{id}")
    public Result findById(@PathVariable String id) {
        User byId = userService.findById(id);
        return new Result(true, "", byId);
    }

    /**
     * 查询全部
     *
     * @param queryPageBean 分页数据
     * @return 返回查询结果
     */
    @PostMapping("findPage")
    public PageResult findAll(@RequestBody QueryPageBean queryPageBean) {
        return userService.findAll(queryPageBean);
    }
}
